package org.fastsyncer.connector.ldap;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.fastsyncer.common.constant.ConnectorConstant;
import org.fastsyncer.common.entity.BaseInfo;
import org.fastsyncer.common.entity.LdapConfig;
import org.fastsyncer.connector.util.LdapUtil;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.filter.GreaterThanOrEqualsFilter;
import org.springframework.ldap.filter.LessThanOrEqualsFilter;
import org.springframework.ldap.filter.NotFilter;
import org.springframework.ldap.filter.OrFilter;

public class LdapConnector implements Ldap {

	private static LdapConnector instance = null;

	public LdapConnector() {
	}

	public static LdapConnector getInstance() {
		if (instance == null) {
			synchronized (LdapConnector.class) {
				instance = new LdapConnector();
			}
		}
		return instance;
	}

	@Override
	public LdapTemplate getLdapTemplate(LdapConfig config) {
		return LdapUtil.getLdapTemplate(config);
	}

	@Override
	public BaseInfo getBaseInfoConnector(LdapConfig config) {
		LdapTemplate ldapTemplate = LdapUtil.getLdapTemplate(config);

		// 且
		AndFilter filter = new AndFilter();
		filter.and(new EqualsFilter("objectclass", "person"));

		BaseInfo connector = LdapUtil.getDataSourceConnector(ldapTemplate, filter.encode());
		return connector;
	}

	public String getFilter(HashMap<String, List<HashMap<String, String>>> query) {
		String defaultFilter = "(objectclass=*)";
		if (query != null && !query.isEmpty()) {
			OrFilter filter = new OrFilter();
			// 拼接并且
			List<HashMap<String, String>> addList = query.get(ConnectorConstant.OPERTION_QUERY_AND);
			this.getOperFilter(ConnectorConstant.OPERTION_QUERY_AND, filter, addList);

			// 拼接或者
			List<HashMap<String, String>> orList = query.get(ConnectorConstant.OPERTION_QUERY_OR);
			this.getOperFilter(ConnectorConstant.OPERTION_QUERY_OR, filter, orList);

			String f = filter.encode();
			return StringUtils.isBlank(f) ? defaultFilter : f;
		}
		return defaultFilter;
	}

	private void getOperFilter(String operator, OrFilter filter, List<HashMap<String, String>> list) {
		if (list == null || list.isEmpty()) {
			return;
		}

		int size = list.size();
		switch (operator) {
		case ConnectorConstant.OPERTION_QUERY_AND:
			AndFilter filterAdd = new AndFilter();
			for (int i = 0; i < size; i++) {
				HashMap<String, String> c = list.get(i);
				String name = c.get("name");
				String oper = c.get("operator");
				String value = c.get("value");
				// 获取查询条件
				Filter f = this.getFilterByOpr(oper, name, value);
				filterAdd.and(f);
			}
			filter.or(filterAdd);
			break;
		case ConnectorConstant.OPERTION_QUERY_OR:
			OrFilter filterOr = new OrFilter();
			for (int i = 0; i < size; i++) {
				HashMap<String, String> c = list.get(i);
				String name = c.get("name");
				String oper = c.get("operator");
				String value = c.get("value");
				// 获取查询条件
				Filter f = this.getFilterByOpr(oper, name, value);
				filterOr.or(f);
			}
			filter.or(filterOr);
			break;
		default:
			break;
		}
	}

	private Filter getFilterByOpr(String oper, String name, String value) {
		Filter f = null;
		switch (oper) {
		case "equal":
			f = new EqualsFilter(name, value);
			break;
		case "notEqual":
			f = new NotFilter(new EqualsFilter(name, value));
			break;
		case "gtAndEqual":
			f = new GreaterThanOrEqualsFilter(name, value);
			break;
		case "ltAndEqual":
			f = new LessThanOrEqualsFilter(name, value);
			break;
		default:
			// 默认相等
			f = new EqualsFilter(name, value);
			break;
		}
		return f;
	}

}
